package com.ruoyi.draw.service.impl;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.draw.mapper.NovelStoryboardMapper;
import com.ruoyi.draw.domain.NovelStoryboard;
import com.ruoyi.draw.service.INovelStoryboardService;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import java.io.File;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.draw.mapper.NovelRoleMapper;
import com.ruoyi.draw.domain.NovelRole;

/**
 * NovelStoryboardService业务层处理
 * 
 * @author Locke
 * @date 2025-10-25
 */
@Service
public class NovelStoryboardServiceImpl implements INovelStoryboardService 
{
    private static final Logger log = LoggerFactory.getLogger(NovelStoryboardServiceImpl.class);
    
    @Autowired
    private NovelStoryboardMapper novelStoryboardMapper;
    
    @Autowired
    private NovelRoleMapper novelRoleMapper;
    
    @Autowired
    private RuoYiConfig ruoyiConfig;

    /**
     * 查询NovelStoryboard
     * 
     * @param id NovelStoryboard主键
     * @return NovelStoryboard
     */
    @Override
    public NovelStoryboard selectNovelStoryboardById(Long id)
    {
        return novelStoryboardMapper.selectNovelStoryboardById(id);
    }

    /**
     * 查询NovelStoryboard列表
     * 
     * @param novelStoryboard NovelStoryboard
     * @return NovelStoryboard
     */
    @Override
    public List<NovelStoryboard> selectNovelStoryboardList(NovelStoryboard novelStoryboard)
    {
        return novelStoryboardMapper.selectNovelStoryboardList(novelStoryboard);
    }

    /**
     * 新增NovelStoryboard
     * 
     * @param novelStoryboard NovelStoryboard
     * @return 结果
     */
    @Override
    public int insertNovelStoryboard(NovelStoryboard novelStoryboard)
    {
        // 检查是否已存在相同的小说ID、章节ID和名称的记录
        NovelStoryboard existingStoryboard = null;
        if (novelStoryboard.getNovelId() != null && novelStoryboard.getNovelChapter() != null && novelStoryboard.getName() != null) {
            NovelStoryboard query = new NovelStoryboard();
            query.setNovelId(novelStoryboard.getNovelId());
            query.setNovelChapter(novelStoryboard.getNovelChapter());
            query.setName(novelStoryboard.getName());
            List<NovelStoryboard> existingList = novelStoryboardMapper.selectNovelStoryboardList(query);
            if (!existingList.isEmpty()) {
                existingStoryboard = existingList.get(0);
            }
        }
        
        // 如果存在相同记录，则更新而不是插入
        if (existingStoryboard != null) {
            // 复用现有记录的ID
            novelStoryboard.setId(existingStoryboard.getId());
            // 更新记录
            return updateNovelStoryboard(novelStoryboard);
        }
        
        // 设置ID和创建信息
        novelStoryboard.setId(System.currentTimeMillis());
        novelStoryboard.setCreateBy(SecurityUtils.getUsername());
        novelStoryboard.setCreateTime(DateUtils.getNowDate());
        
        //这里需要拼接图片 首先roles是萧薰儿,萧炎这样的数据，你需要分离,拿到角色的名称
        //List<String> name 拿到这个根据name去查询角色图片路径
        //再根据路径把所有的图片合并成一张图片 再把这种图片的路径设置为img
        String roles = novelStoryboard.getRefRole();
        if (roles != null && !roles.isEmpty()) {
            // 分离角色名称
            List<String> roleNames = Arrays.asList(roles.split(","));
            
            // 根据小说ID和角色名称查询角色信息
            List<NovelRole> novelRoles = novelRoleMapper.selectNovelRolesByNovelIdAndNames(novelStoryboard.getNovelId(), roleNames);
            
            // 获取角色图片路径
            List<String> imagePaths = novelRoles.stream()
                .map(NovelRole::getRoleImg)
                .filter(img -> img != null && !img.isEmpty())
                .collect(Collectors.toList());
            
            // 合并图片
            if (!imagePaths.isEmpty()) {
                try {
                    String mergedImagePath = mergeImagesHorizontally(imagePaths, novelStoryboard.getId());
                    // 将合并后的图片路径保存到img字段
                    novelStoryboard.setImg(mergedImagePath);
                                
                    // 如果res_img为空，设置默认值
                    if (novelStoryboard.getRes_img() == null || novelStoryboard.getRes_img().isEmpty()) {
                        novelStoryboard.setRes_img(mergedImagePath);
                    }
                } catch (Exception e) {
                    log.error("合并图片时发生错误", e);
                }
            }
        }
        
        return novelStoryboardMapper.insertNovelStoryboard(novelStoryboard);
    }

    /**
     * 水平拼接图片
     * 
     * @param imagePaths 图片路径列表
     * @param storyboardId 分镜ID，用于生成唯一文件名
     * @return 合并后图片的路径
     * @throws IOException 读取或写入图片时发生错误
     */
    private String mergeImagesHorizontally(List<String> imagePaths, Long storyboardId) throws Exception {
        if (imagePaths.isEmpty()) {
            return null;
        }
        
        log.debug("开始合并图片，图片数量: {}", imagePaths.size());
        
        // 读取所有图片
        BufferedImage[] images = new BufferedImage[imagePaths.size()];
        int totalWidth = 0;
        int maxHeight = 0;
        
        for (int i = 0; i < imagePaths.size(); i++) {
            String imagePath = imagePaths.get(i);
            log.debug("处理图片: {}", imagePath);
            // 处理图片路径，可能需要转换为绝对路径
            String absolutePath = getAbsoluteImagePath(imagePath);
            File imageFile = new File(absolutePath);
            if (imageFile.exists()) {
                images[i] = ImageIO.read(imageFile);
                totalWidth += images[i].getWidth();
                maxHeight = Math.max(maxHeight, images[i].getHeight());
                log.debug("图片读取成功，尺寸: {}x{}", images[i].getWidth(), images[i].getHeight());
            } else {
                log.warn("图片文件不存在: {}", absolutePath);
                throw new IOException("图片文件不存在: " + absolutePath);
            }
        }
        
        // 创建合并后的图片
        BufferedImage combined = new BufferedImage(totalWidth, maxHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = combined.createGraphics();
        
        // 绘制所有图片
        int currentX = 0;
        for (BufferedImage image : images) {
            g2d.drawImage(image, currentX, 0, null);
            currentX += image.getWidth();
        }
        
        g2d.dispose();
        
        // 保存合并后的图片
        String outputPath = "/profile/upload/storyboard/" + storyboardId + "_merged.png";
        String absoluteOutputPath = ruoyiConfig.getUploadPath() + "/storyboard/" + storyboardId + "_merged.png";
        
        log.debug("保存合并图片到: {}", absoluteOutputPath);
        
        // 确保输出目录存在
        Path outputDir = Paths.get(ruoyiConfig.getUploadPath(), "storyboard");
        if (!Files.exists(outputDir)) {
            Files.createDirectories(outputDir);
        }
        
        File outputFile = new File(absoluteOutputPath);
        ImageIO.write(combined, "png", outputFile);
        
        log.debug("图片合并完成，保存路径: {}", outputPath);
        return outputPath;
    }
    
    /**
     * 获取图片的绝对路径
     * 
     * @param imagePath 图片路径
     * @return 图片的绝对路径
     */
    private String getAbsoluteImagePath(String imagePath) {
        if (imagePath.startsWith("/profile/upload")) {
            // 转换为绝对路径
            String relativePath = imagePath.substring("/profile/upload".length());
            return ruoyiConfig.getUploadPath() + relativePath;
        }
        return ruoyiConfig.getUploadPath() + imagePath;
    }

    /**
     * 修改NovelStoryboard
     * 
     * @param novelStoryboard NovelStoryboard
     * @return 结果
     */
    @Override
    public int updateNovelStoryboard(NovelStoryboard novelStoryboard)
    {
        novelStoryboard.setUpdateBy(SecurityUtils.getUsername());
        novelStoryboard.setUpdateTime(DateUtils.getNowDate());
        
        // 如果res_img为空，设置默认值
        if (novelStoryboard.getRes_img() == null || novelStoryboard.getRes_img().isEmpty()) {
            novelStoryboard.setRes_img(novelStoryboard.getImg());
        }
        
        return novelStoryboardMapper.updateNovelStoryboard(novelStoryboard);
    }

    /**
     * 批量删除NovelStoryboard
     * 
     * @param ids 需要删除的NovelStoryboard主键
     * @return 结果
     */
    @Override
    public int deleteNovelStoryboardByIds(Long[] ids)
    {
        return novelStoryboardMapper.deleteNovelStoryboardByIds(ids);
    }

    /**
     * 删除NovelStoryboard信息
     * 
     * @param id NovelStoryboard主键
     * @return 结果
     */
    @Override
    public int deleteNovelStoryboardById(Long id)
    {
        return novelStoryboardMapper.deleteNovelStoryboardById(id);
    }
    
    /**
     * 从docx文件中提取文字
     * 
     * @param filePath 文件路径
     * @return 提取的文字内容
     * @throws Exception 提取过程中可能发生的异常
     */
    @Override
    public String extractTextFromDocx(String filePath) throws Exception {
        StringBuilder text = new StringBuilder();

        String uploadPath = ruoyiConfig.getUploadPath();
        System.out.println(uploadPath);
        System.out.println(filePath);
        String cleanPath = filePath.replaceFirst("^/profile/upload", "");
        //删除filePath 开头的/profile/upload
        System.out.println(cleanPath);
        String realPath = uploadPath+cleanPath;

        System.out.println(realPath);
        // 检查文件是否存在
        File file = new File(realPath);
        if (!file.exists()) {
            throw new Exception("文件不存在: " + filePath);
        }
        
        // 获取输入流
        try (InputStream inputStream = new FileInputStream(file)) {
            // 使用Apache POI读取docx文件
            XWPFDocument document = new XWPFDocument(inputStream);
            
            // 遍历段落提取文字
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                text.append(paragraph.getText()).append("\n");
            }
            
            // 关闭文档
            document.close();
        }
        
        return text.toString();
    }
    
    /**
     * 根据小说ID和章节ID查询分镜列表
     * 
     * @param novelId 小说ID
     * @param chapterId 章节ID
     * @return 分镜列表
     */
    @Override
    public List<NovelStoryboard> selectNovelStoryboardByNovelIdAndChapter(Long novelId, Long chapterId) {
        log.debug("根据小说ID和章节ID查询分镜列表: novelId={}, chapterId={}", novelId, chapterId);
        List<NovelStoryboard> result = novelStoryboardMapper.selectNovelStoryboardByNovelIdAndChapter(novelId, chapterId);
        log.debug("查询结果数量: {}", result.size());
        return result;
    }
}